package com.example.hometown_walker.service.design.creation.abstract_factory;

/**
 * @description: 抽象工厂模式
 * @author: chenchaoran
 * @date: 2020-03-15
 */
public class AbstractFactoryMain {
    public static void main(String[] args) {
        // 使用者不必关心生产细节区别等，只需按需使用
        AbstractPenFactory lowFactory = new LowEndPenFactory();
        lowFactory.produceBlackPen().write();
        lowFactory.produceRedPen().write();

        AbstractPenFactory highFactory = new HighEndPenFactory();
        highFactory.produceBlackPen().write();
        highFactory.produceRedPen().write();
    }
}


interface IPen {
    /**
     * 该例定义的产品族均为笔，可以抽象出该接口
     * 如果产品族差异性较大，不存在共同行为，则不用抽象出该接口。 此类非必须！
     */
    void write();
}

/**
 * 定义：
 * 产品族1：black pen
 * 产品族2：red pen
 *
 * 两种产品族，又包含相同的产品类型：昂贵型、便宜型
 */
abstract class AbstractBlackPen implements IPen{
    public String getColor() {
        return "Black";
    }
}

abstract class AbstractRedPen implements IPen{
    abstract int getPrice();
}

/**
 * 具体产品：族 x 类型
 */
class ExpensiveBlackPen extends AbstractBlackPen {

    @Override
    public void write() {
        System.out.println("I am expensive black pen. i am writing now.");
    }
}

class CheapBlackPen extends AbstractBlackPen {

    @Override
    public void write() {
        System.out.println("I am cheap black pen. i am writing now.");
    }
}

class ExpensiveRedPen extends AbstractRedPen {

    @Override
    public void write() {
        System.out.println("I am expensive red pen. i am writing now.");
    }

    @Override
    int getPrice() {
        return 3;
    }
}

class CheapRedPen extends AbstractRedPen {

    @Override
    public void write() {
        System.out.println("I am cheap red pen. i am writing now.");
    }

    @Override
    int getPrice() {
        return 10;
    }
}



/**
 * 定义抽象工厂--能够生产所有产品族
 */
abstract class AbstractPenFactory {
    abstract AbstractBlackPen produceBlackPen();
    abstract AbstractRedPen produceRedPen();
}


/**
 * 定义工厂实现：
 * 不同的实现类，负责生产产品族的不同类型产品
 *
 * 高端工厂：生产昂贵型
 *
 */
class HighEndPenFactory extends AbstractPenFactory{

    @Override
    AbstractBlackPen produceBlackPen() {
        // 生产黑笔芯
        // 生产黑笔壳
        // 组装...
        // 复杂的制造过程............
        return new ExpensiveBlackPen();
    }

    @Override
    AbstractRedPen produceRedPen() {
        // 复杂的制造过程.............
        return new ExpensiveRedPen();
    }
}

/**
 * 低端工厂：生产便宜型
 */
class LowEndPenFactory extends AbstractPenFactory {

    @Override
    AbstractBlackPen produceBlackPen() {
        // 复杂的制造过程.............
        return new CheapBlackPen();
    }

    @Override
    AbstractRedPen produceRedPen() {
        // 复杂的制造过程.............
        return new CheapRedPen();
    }
}
